11. 梯度下降
到达谷底
现在,我将简单复习下梯度下降概念,使我们能够开始用 MiniFlow 训练我们的网络。注意,我们的目标是通过尽量减小代价,使我们的网络输出与目标值尽量接近。你可以将代价看做一座山,我们想要到达山底。
想象你的模型参数表示为一个停在山顶的球。直观地来说,我们希望将球推下山。这样可以明白,但是我们讨论的是代价函数,如何知道哪条路是下山呢?
幸运的是,梯度下降正好给出了这一信息。
严格来说,梯度实际上指的是上坡,是最陡上升方向。但是,如果我们在此值前面加个负号,就得出了最陡下降方向,这正是我们需要的。
稍后你将详细了解梯度,但是暂时可以将其看做数字向量。每个数字表示我们应该对照着调整神经网络中相应的权重或偏置的数量。按照梯度值调整所有的权重和偏置降低了网络的代价(或误差)。
听明白了吗?
好的!现在我们知道朝着哪个方向推球了。下一步是考虑用多大的推力,称之为学习速度,该名称比较恰当,因为该值确定了神经网络学习的快慢速度。
你可能希望设置非常大的学习速度,这一网络就能学的非常快,对吧?
要小心!如果该值太大,可能会迭代过度并最终偏离目标。呀!

收敛。这是理想的行为。

发散。当学习速度过高时会出现这种情况。
那么,什么样的学习速度合适呢?
我们只能做出猜测,根据以往经验,0.1 至 0.0001 范围的值效果最好。0.001 至 0.0001 范围的值很常见,因为 0.1 和 0.01 有时候过大。
下面是梯度下降的公式(伪代码):
x = x - learning_rate * gradient_of_x
x
是神经网络使用的参数(即单个权重或偏置)。
我们将 gradient_of_x
(上坡方向)与 learning_rate
(推力)相乘,然后将 x
减去相乘结果,从而向下推动。
太棒了!现在来做一道练习吧。
设置
对于这道测验,你将完成 f.py
和 gd.py
文件中的 TODO
。
任务:
- 在
f.py
中设置learning_rate
。 - 在
gd.py
的gradient_descent_update
函数中完成梯度下降的实现代码。
备注:
- 如果你正确地实现了梯度下降代码,将
learning_rate
设为 0.1 应该得出x
-> 0 及f(x)
-> 5。 - 将学习速度设为不同的值,看看效果如何。试试非常小的值、接近 1 的值、大于 1 的值,等等。会出现什么情况?
Start Quiz:
"""
Given the starting point of any `x` gradient descent
should be able to find the minimum value of x for the
cost function `f` defined below.
"""
import random
from gd import gradient_descent_update
def f(x):
"""
Quadratic function.
It's easy to see the minimum value of the function
is 5 when is x=0.
"""
return x**2 + 5
def df(x):
"""
Derivative of `f` with respect to `x`.
"""
return 2*x
# Random number between 0 and 10,000. Feel free to set x whatever you like.
x = random.randint(0, 10000)
# TODO: Set the learning rate
learning_rate = None
epochs = 100
for i in range(epochs+1):
cost = f(x)
gradx = df(x)
print("EPOCH {}: Cost = {:.3f}, x = {:.3f}".format(i, cost, gradx))
x = gradient_descent_update(x, gradx, learning_rate)
def gradient_descent_update(x, gradx, learning_rate):
"""
Performs a gradient descent update.
"""
# TODO: Implement gradient descent.
# Return the new value for x
return x
import f